/**
 * 
 */
package net.toocruel.iqismart.service.core.impl;


import net.toocruel.iqismart.dao.UserRepository;
import net.toocruel.iqismart.dao.core.AnswerRepository;
import net.toocruel.iqismart.dao.core.AttentionRepository;
import net.toocruel.iqismart.dao.core.QuestionRepository;
import net.toocruel.iqismart.entity.constants.Action;
import net.toocruel.iqismart.entity.constants.NotificationType;
import net.toocruel.iqismart.entity.constants.SourceType;
import net.toocruel.iqismart.entity.core.Answer;
import net.toocruel.iqismart.entity.core.Attention;
import net.toocruel.iqismart.entity.core.Credit;
import net.toocruel.iqismart.entity.core.Notification;
import net.toocruel.iqismart.entity.rbac.User;
import net.toocruel.iqismart.service.UserService;
import net.toocruel.iqismart.service.core.AnswerService;
import net.toocruel.iqismart.service.core.NotificationService;
import net.toocruel.iqismart.service.exception.AccessDeniedException;
import net.toocruel.iqismart.service.helper.UserHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @author toocruel
 *
 */
@Service
@Transactional
public class AnswerServiceImpl implements AnswerService {
    @Autowired
    private AnswerRepository answerRepository;

    @Autowired
    private QuestionRepository questionRepository;

    @Autowired
    private AttentionRepository attentionRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private NotificationService notificationService;

    @Override
    public Answer postAnswer(Answer answer, Boolean follow) {
        answer.setId(null);
        answer = answerRepository.save(answer);

        //关注问题
        Answer finalAnswer = answer;
        Attention oldAttention = attentionRepository.findOne((root, query, cb) -> {
            return cb.and(cb.equal(root.get("question"), finalAnswer.getQuestion()),
                    cb.equal(root.get("user"), finalAnswer.getUser()),
                    cb.equal(root.get("sourceType"), SourceType.question));
        });
        if(oldAttention == null){
            if(follow != null && follow) {
                Attention attention = new Attention();
                attention.setQuestion(answer.getQuestion());
                attention.setUser(answer.getUser());
                attention.setSourceType(SourceType.question);
                attentionRepository.save(attention);
            }
        }else{
            if(follow != null && !follow) {
                attentionRepository.delete(oldAttention);
            }
        }

        answer.getQuestion().setLastAnswer(System.currentTimeMillis());
        answer.getQuestion().setAnswerNum(answer.getQuestion().getAnswerNum()+1);
        questionRepository.save(answer.getQuestion());

        //积分奖励
        userService.addCredit(new Credit(answer.getUser(),Action.CREATE_ANSWER,answer.getQuestion(),answer));

        //提醒用户
        User toUser = answer.getQuestion().getUser();
        if(toUser.getSiteNotifications().contains(NotificationType.ANSWER_QUESTION)){
            Notification notification = new Notification();
            notification.setToUser(toUser);
            notification.setFromUser(answer.getUser());
            notification.setQuestion(answer.getQuestion());
            notificationService.send(notification);
        }
        if(toUser.getEmailNotifications().contains(NotificationType.ANSWER_QUESTION)){
            //TODO 如果需要发送邮件
        }
        return answer;
    }

    @Override
    public Answer findById(Long id) {
        return answerRepository.findOne((root, query, cb) ->{
            root.fetch("question");
            return cb.equal(root.get("id"),id);
        });
    }

    @Override
    public Answer update(Answer answer) {
        Answer _answer = answerRepository.findOne(answer.getId());
        _answer.setContent(answer.getContent());
        answer = answerRepository.save(_answer);
        return answer;
    }

    @Override
    public void adopt(Long id) {
        Answer answer = answerRepository.findOne(id);
        if(!answer.getQuestion().getUser().getId().equals(UserHelper.getCurrentUser().getId()) && !UserHelper.getCurrentUser().getAdmin()){
            throw new AccessDeniedException();
        }

        answer.setAdoptedAt(new Date());
        answerRepository.save(answer);

        answer.getQuestion().setBestAnswer(answer);
        answer.getQuestion().setStatus(2);

        questionRepository.save(answer.getQuestion());

        //积分奖励
        userService.addCredit(new Credit(answer.getUser(),Action.ANSWER_ADOPTED,answer.getQuestion(),answer));

       userService.updateAdoptPercent(answer.getUser().getId());


        if(answer.getUser().getSiteNotifications().contains(NotificationType.ADOPT_ANSWER)){
            Notification notification = new Notification();
            notification.setType(NotificationType.ADOPT_ANSWER);
            notification.setToUser(answer.getUser());
            notification.setFromUser(userRepository.findOne(UserHelper.getCurrentUser().getId()));
            notification.setQuestion(answer.getQuestion());
            notification.setAnswer(answer);
            notificationService.send(notification);
        }
        if(answer.getUser().getEmailNotifications().contains(NotificationType.ADOPT_ANSWER)){
            //TODO 发送邮件
        }


    }
}
